package com.gin.kotlin.gf2gamecommunity.routes

import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import androidx.navigation.toRoute
import com.gin.kotlin.gf2gamecommunity.R
import com.gin.kotlin.gf2gamecommunity.app.App
import com.gin.kotlin.gf2gamecommunity.base.composable.ConfirmDialog
import com.gin.kotlin.gf2gamecommunity.base.composable.IntSliderDialog
import com.gin.kotlin.gf2gamecommunity.base.composable.MyImage
import com.gin.kotlin.gf2gamecommunity.navi.GF2Navigator
import com.gin.kotlin.gf2gamecommunity.viewmodel.ExchangeItemViewModel
import com.gin.kotlin.gf2gamecommunity.viewmodel.UserViewModel
import com.gin.kotlin.response.item.ExchangeableItem
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable

fun NavGraphBuilder.exchangeItem(navigator: GF2Navigator) = composable<ExchangeItemRoute>(
    // 从屏幕右侧进入，持续500毫秒
    enterTransition = { slideInHorizontally(tween(500)) { it } },
    // 从屏幕右侧退出，持续500毫秒
    exitTransition = { slideOutHorizontally(tween(500)) { it } }) {
    ExchangeItemComposable(route = it.toRoute(), navigator = navigator)
}

@Serializable
data class ExchangeItemRoute(val id: Int = 1)


@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ExchangeItemComposable(route: ExchangeItemRoute, viewModel: ExchangeItemViewModel = viewModel(), userViewModel: UserViewModel = viewModel(), navigator: GF2Navigator) {
    val userInfoState = userViewModel.cUser.liveData.observeAsState()
    val state = viewModel.exchangeList.liveData.observeAsState()
    var selectedItem by remember { mutableStateOf(ExchangeableItem()) }
    var showExchangeDialog by remember { mutableStateOf(false) }
    var showExchangeAllDialog by remember { mutableStateOf(false) }

    userViewModel.fetchCurrentUserInfo()
    viewModel.exchangeList.fetch()

    Scaffold(topBar = {
        TopAppBar(title = { Text("道具兑换") }, actions = {
            IconButton(
                onClick = { navigator.onNavigateToScoreLog(ScoreLogRoute()) }) {
                Icon(painterResource(R.drawable.ic_history_24), contentDescription = "积分变动记录")
            }
            IconButton(
                enabled = state.value?.any { it.maxExchangeCount != it.exchangeCount } == true,
                onClick = { showExchangeAllDialog = true }) {
                Icon(painterResource(R.drawable.ic_airplanemode_active_24), contentDescription = "一键兑换")
            }
        })
    }) { padding ->
        val modifier = Modifier.padding(padding)
        Column(modifier = modifier) {
            Text("当前积分: ${userInfoState.value?.score}")
            HorizontalDivider(Modifier.height(4.dp))
            LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 180.dp)) {
                state.value?.also { list ->
                    items(items = list) {
                        ExchangeItem(it, onClick = { item ->
                            selectedItem = item
                            showExchangeDialog = true
                        })
                    }
                }
            }
        }
    }

    when {
        showExchangeDialog -> {
            val scope = rememberCoroutineScope()
            var text by remember { mutableStateOf("") }
            IntSliderDialog(
                max = selectedItem.maxExchangeCount - selectedItem.exchangeCount,
                onDismissRequest = { showExchangeDialog = false },
                onConfirmation = { count ->
                    scope.launch {
                        viewModel.exchange(
                            selectedItem.exchangeId, count,
                            onSuccess = { success -> text = "${selectedItem.itemName} $success / $count 已兑换" },
                            onCompleted = { success ->
                                text = "${selectedItem.itemName} $success / $count 兑换完毕"
                                delay(2000)
                                showExchangeDialog = false
                                viewModel.exchangeList.fetch(true)
                            },
                        )
                    }
                },
                content = {
                    if (text.isNotEmpty())
                        Text(text)
                    else
                        Text("兑换 ${selectedItem.itemName} $it 个")
                })
        }

        showExchangeAllDialog -> {
            val scope = rememberCoroutineScope()

            val score = userInfoState.value?.score
            val exchangeAbleItems = viewModel.exchangeList.liveData.value?.takeIf { it.isNotEmpty() }?.filter { it.exchangeable() }
            val sumPrice = exchangeAbleItems?.sumOf { (it.exchangeableCount()) * it.useScore }

            when {
                score == null || sumPrice == null -> {
                    App.toast("无法一键兑换: 数据不足")
                    showExchangeAllDialog = false
                }

                score < sumPrice -> {
                    App.toast("无法一键兑换: 积分不足")
                    showExchangeAllDialog = false
                }

                exchangeAbleItems.isEmpty() -> {
                    App.toast("无法一键兑换: 无可兑换道具")
                    showExchangeAllDialog = false
                }

                else -> {
                    val messages = remember { mutableStateListOf<String>() }
                    ConfirmDialog(onDismissRequest = { showExchangeAllDialog = false }, onConfirmation = {
                        scope.launch {
                            viewModel.exchangeAll(exchangeAbleItems) { item, _ ->
                                messages.add("兑换成功: ${item.itemName}")
                            }
                            delay(2000)
                            showExchangeAllDialog = false
                        }
                    }) {
                        if (messages.isNotEmpty()) {
                            LazyColumn { items(items = messages) { Text(it) } }
                        } else {
                            Text("兑换所有道具？")
                        }
                    }
                }
            }
        }
    }
}

@Composable
private fun ExchangeItem(item: ExchangeableItem, onClick: (item: ExchangeableItem) -> Unit = {}) {
    val sellout = item.exchangeCount == item.maxExchangeCount
    Box(contentAlignment = Alignment.Center, modifier = Modifier.clickable { if (!sellout) onClick(item) }) {
        Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.graphicsLayer {
            alpha = if (sellout) 0.3f else 1f
        }) {
            MyImage(item.itemPic)
            Text("${item.itemName} x${item.itemCount}")
            Row(horizontalArrangement = Arrangement.SpaceBetween) {
                Text("单价: ${item.useScore}")
                Spacer(Modifier.width(16.dp))
                Text("限购: ${item.maxExchangeCount - item.exchangeCount}/${item.maxExchangeCount}")
            }
        }
        if (sellout) Text("售罄")
    }
}